package cn.mw.cmdb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.enums.InterfaceInfoEnum;
import cn.mw.cmdb.enums.MonitoringServerType;
import cn.mw.cmdb.exception.FindNoException;
import cn.mw.cmdb.exception.FindNotTemplateException;
import cn.mw.cmdb.mongoMapper.AssetsInterfaceMapper;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.param.zabbixResult.DiscoveryRuleParam;
import cn.mw.cmdb.param.zabbixResult.MwItemCheckNowParam;
import cn.mw.cmdb.param.zabbixResult.ValueMappingDto;
import cn.mw.cmdb.param.zabbixResult.ValuemapDto;
import cn.mw.cmdb.processor.*;
import cn.mw.cmdb.service.AssetsManageService;
import cn.mw.cmdb.task.AssetScanServiceContext;
import cn.mw.cmdb.task.AssetsDiscoveryRunManage;
import cn.mw.cmdb.template.param.ZabbixHandlerParam;
import cn.mw.cmdb.template.service.MwZabbixHandlerService;
import cn.mw.cmdb.util.AlphanumericComparator;
import cn.mw.cmdb.util.AssetsTool;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.view.ViewConvertContext;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.components.dubbo.config.DubboUtils;
import cn.mw.components.mongodb.entity.*;
import cn.mw.components.mongodb.page.MWPage;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.common.MwEngineManageService;
import cn.mw.microMonitorCommon.api.common.MwTPServerService;
import cn.mw.microMonitorCommon.api.scan.AssetScanService;
import cn.mw.microMonitorCommon.api.scan.ScanParam;
import cn.mw.microMonitorCommon.api.scan.ScanResult;
import cn.mw.microMonitorCommon.api.scan.ScanResultSuccess;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.entity.cmdb.AssetsInterfaceView;
import cn.mw.microMonitorCommon.entity.cmdb.MwProxyTypeEnum;
import cn.mw.microMonitorCommon.entity.common.MwEngineManageTableDto;
import cn.mw.microMonitorCommon.entity.common.MwEngineProxyGroupInfo;
import cn.mw.microMonitorCommon.entity.common.MwTPServerTable;
import cn.mw.microMonitorCommon.entity.scan.DubboServiceInfo;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.enums.RuleType;
import cn.mw.microMonitorCommon.util.SpringUtils;
import cn.mw.microMonitorCommon.utils.DatabaseUtils;
import cn.mw.scanengine.entity.ScanEngineInfo;
import cn.mw.scanengine.service.ScanEngineService;
import cn.mw.scanengine.snmp.scan.model.IfMode;
import cn.mw.scanengine.snmp.scan.model.IfStatus;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.cluster.specifyaddress.Address;
import org.apache.dubbo.rpc.service.EchoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Pair;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.mw.cmdb.controller.AssetsManageController.*;
import static cn.mw.cmdb.enums.ModelViewTypeEnum.defaultView;
import static cn.mw.cmdb.enums.MonitorModeType.ICMP;
import static cn.mw.cmdb.util.CMDBCommonUtil.filterListByMap;
import static cn.mw.cmdb.util.ValConvertUtil.*;
import static cn.mw.components.mongodb.entity.MongoPropertyType.strValueConvert;
import static cn.mw.components.mongodb.tool.MongoUtils.genCriteria;

/*
 * 如果是通过k8s发布, 必须有一台扫描引擎与cmdb在同一个ip
 */
@Service
@Slf4j
public class AssetsManageServiceImpl implements AssetsManageService {
    private DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final String INTERFACE_NAME_VLAN_KEY = "Vlan";

    public static final String TEMPLATE_MAP_KEY = "templateInfoMapById";
    public static final String GROUP_MAP_KEY = "groupInfoMapById";
    public static final String PROXY_MAP_KEY = "proxyIdById";
    public static final String ICMP_Temp_Name = "ICMP_通用模版";
    //拓扑缓存刷新指令
    private String RefreshInterfaceMapCache = "RefreshInterfaceMapCache";
    private String RefreshInterfaceTopic = "topo-cache";

    public String systemInterfaceConfigKey = "system.interfaceInfo.configName";

    public String SCMONITORSYSTEMKEY = "scMonitorSystem";


    @Value("${cmdb.scan.debug}")
    private boolean debug;

    private ScanEngineService scanEngineService;

    private CmdbServiceManage cmdbServiceManage;

    private BusinessProcessNetwork businessProcessNetwork;

    private KafkaTemplate<String, String> kafkaTemplate;
    public static final String InstanceIdKey = "instanceId";
    @DubboReference(check = false, timeout = 120000)
    private ZabbixDubboService zabbixDubboService;
    private int batchFetchNum = 1000;
    @DubboReference(check = false, mock = "true", timeout = 15000)
    private MwEngineManageService mwEngineManageService;
    @Autowired
    private MwZabbixHandlerService mwZabbixHandlerService;
    @DubboReference(check = false, mock = "true", timeout = 15000)
    private MwTPServerService mwTPServerService;

    private ViewManager viewManager;

    private AssetsInterfaceMapper assetsInterfaceMapper;

    public AssetsManageServiceImpl(CmdbServiceManage cmdbServiceManage, ScanEngineService scanEngineService
            , BusinessProcessNetwork businessProcessNetwork, KafkaTemplate<String, String> kafkaTemplate, ViewManager viewManager, AssetsInterfaceMapper assetsInterfaceMapper) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.scanEngineService = scanEngineService;
        this.businessProcessNetwork = businessProcessNetwork;
        this.kafkaTemplate = kafkaTemplate;
        this.viewManager = viewManager;
        this.assetsInterfaceMapper = assetsInterfaceMapper;
    }

    //资产扫描并设置扫描成功信息
    @Override
    public ScanResult assetScan(AssetsScanParam assetsScanParam) throws Exception {
        AssetsDiscoveryRunManage runManage = SpringUtils.getBean(AssetsDiscoveryRunManage.class);
        ScanResult scanResult = new ScanResult();
        //单个资产扫描时,前端接口传参与批量扫描时不一致
        //需要进行转换
        if (StringUtils.hasText(assetsScanParam.getMw_ruleType())
                && null == assetsScanParam.getRuleParams()) {
            AssetsTool.convertSingleScanParam(assetsScanParam);
        }
        //ICMP特殊处理，直接返回数据
        if (StringUtils.hasText(assetsScanParam.getMw_ruleType()) && RuleType.getInfoByName(assetsScanParam.getMw_ruleType()).equals(RuleType.ICMP)) {
            scanResult = getICMPAssetsScanResult(assetsScanParam);
            return scanResult;
        }
        //获取扫描结果
        InetAddress cmdbIp = NetUtils.getLocalAddress();
        log.info("assetsScanParam:{}", assetsScanParam);
        log.info("cmdbIp:{}", cmdbIp.getHostAddress());
        List<String> engineIds = new ArrayList<>();

        Integer proxyType = assetsScanParam.getMw_proxyType();
        ScanEngineInfo scanEngineInfo = null;
        if (null != proxyType && MwProxyTypeEnum.proxyGroup.getCode().equals(proxyType)) {
            //根据分组查询引擎信息
            String groupId = assetsScanParam.getMw_pollingEngine();
            String key = ScanEngineInfo.getGroupKey(groupId);
            scanEngineInfo = new ScanEngineInfo(key);
            List<String> proxyGroups = new ArrayList<>();
            proxyGroups.add(groupId);
            List<MwEngineManageTableDto> mwEngineManageTableDtos = mwEngineManageService.getEngineManageByGroupIds(proxyGroups);
            for (MwEngineManageTableDto mwEngineManageTableDto : mwEngineManageTableDtos) {
                engineIds.add(mwEngineManageTableDto.getId());
                scanEngineInfo.addEngineId(mwEngineManageTableDto.getId());
            }
        } else if (!Strings.isNullOrEmpty(assetsScanParam.getMw_pollingEngine())) {
            scanEngineInfo = new ScanEngineInfo(assetsScanParam.getMw_pollingEngine());
            engineIds.add(assetsScanParam.getMw_pollingEngine());
        } else {
            scanEngineInfo = new ScanEngineInfo(ScanEngineInfo.localEngineKey);
        }

        log.info("engineIds {}", engineIds);
        List<Instance> dubboInstances = scanEngineService.listInstances();
        Map<String, List<DubboServiceInfo<AssetScanService>>> assetScanServiceMap = scanEngineService.getDubboServiceMap(AssetScanService.class, engineIds, dubboInstances);
        scanEngineInfo.setAssetScanServiceMap(assetScanServiceMap);
        List<DubboServiceInfo<AssetScanService>> assetScanServices = scanEngineInfo.getAssetScanServices();

        ScanParam scanParam = new ScanParam();
        BeanUtils.copyProperties(assetsScanParam, scanParam);

        scanResult.init();
        if (assetScanServices.size() > 0) {
            //信息匹配前准备,获取模版信息
            ModelTemplateServiceImpl modelTemplateService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
            List<Integer> monitorModes = new ArrayList<Integer>();
            if (null != assetsScanParam.getRuleParams() && assetsScanParam.getRuleParams().size() > 0) {

                assetsScanParam.getRuleParams().forEach(ruleParam -> {
                    RuleType ruleType = RuleType.getInfoByName(ruleParam.getRuleType());
                    monitorModes.add(ruleType.getMonitorMode());
                });
            }

            Query query = new Query(CriteriaWrapper.where(ModelTemplateInfo::getMonitorMode).in(monitorModes));
            List<ModelTemplateInfo> modelTemplateInfos = modelTemplateService.getListByQuery(query);

            int threadCount = assetScanServices.size();
            ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
            List<Future<ScanResult>> futures = new ArrayList<>();

            for (DubboServiceInfo<AssetScanService> dubboServiceInfo : assetScanServices) {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                AssetScanService assetScanService = dubboServiceInfo.getDubboService();
                Address dubboRpcAddress = new Address(dubboServiceInfo.getIp(), dubboServiceInfo.getPort());
                ScanTask scanTask = new ScanTask(authentication, assetScanService, scanParam, cmdbServiceManage
                        , assetsScanParam, this, modelTemplateInfos, dubboRpcAddress);
                Future<ScanResult> future = executorService.submit(scanTask);

                AssetScanServiceContext assetScanServiceContext = new AssetScanServiceContext(assetScanService, assetsScanParam.getTaskId(), future);
                runManage.checkAndAddTask(assetsScanParam.getTaskId(), assetScanServiceContext);
                futures.add(future);
            }

            for (Future<ScanResult> future : futures) {
                ScanResult ret = null;
                try {
                    ret = future.get();
                } catch (InterruptedException interruptedException) {
                    log.info("scanTask is interrupt");
                } catch (CancellationException cancellationException) {
                    log.info("scanTask is canceled");
                }
                if (null != ret) {
                    if (null != ret.getScanResultSuccesses() && ret.getScanResultSuccesses().size() > 0) {
                        scanResult.addAllSuccess(ret.getScanResultSuccesses());
                    }

                    if (null != ret.getErrors() && ret.getErrors().size() > 0) {
                        scanResult.addAllFails(ret.getErrors());
                    }
                }
            }

            for (DubboServiceInfo<AssetScanService> dubboServiceInfo : assetScanServices) {
                ReferenceConfig referenceConfig = (ReferenceConfig) dubboServiceInfo.getReferenceConfig();
                referenceConfig.destroy();
            }
            executorService.shutdown();
        }

        //回显设置监控服务器和轮训引擎
        if (null != scanResult.getScanResultSuccesses()) {
            for (ScanResultSuccess scanResultSuccess : scanResult.getScanResultSuccesses()) {
                if (ICMP.getName().equals(scanResultSuccess.getRuleType().getName())) {

                }


                if (assetsScanParam.getMw_monitorServerId() != null) {
                    scanResultSuccess.setMonitorServerId(assetsScanParam.getMw_monitorServerId());
                }
                scanResultSuccess.setProxyType(assetsScanParam.getMw_proxyType());
                if (StringUtils.hasText(assetsScanParam.getMw_pollingEngine())) {
                    scanResultSuccess.setPollingEngine(assetsScanParam.getMw_pollingEngine());
                }
                if (StringUtils.hasText(scanResultSuccess.getHostName())) {
                    scanResultSuccess.setInstanceName(scanResultSuccess.getHostName());
                }
            }
        }

        return scanResult;
    }

    @Override
    public void addMonitor(MonitorValue monitorValue) throws Exception {
        MonitorParamContext context = MonitorParamContext.build();
        doMonitor(monitorValue, context, monitorProcessor -> {
            monitorProcessor.monitor(context);
        });
    }

    @Override
    public void batchAddMonitor(List<? extends MonitorValue> monitorValueList) throws Exception {
        MonitorParamContext context = MonitorParamContext.build();
        doBatchMonitor(monitorValueList, context, monitorProcessor -> {
            monitorProcessor.batchMonitor(context);
        });
    }

    @Override
    public void delMonitor(MonitorValue monitorValue) throws Exception {
        MonitorParamContext context = MonitorParamContext.build();
        doMonitor(monitorValue, context, monitorProcessor -> {
            monitorProcessor.removeMonitor(context);
        });
    }

    @Override
    public Object failAssetsScan(AssetsScanFailParam param) throws Exception {
        AssetsDiscoverServiceImpl assetsDiscoverService = (AssetsDiscoverServiceImpl) this.cmdbServiceManage.getModelService(AssetsDiscoverServiceImpl.ID);
        assetsDiscoverService.failAssetsScan(param);
        return assetsDiscoverService.getAssetDiscoverInfoListByIds(Collections.singletonList(param.getId()));
    }

    @Override
    public void refreshAssetsIfInfo() throws Exception {
        //查询snmp资产并更新接口信息
        log.info("start refreshAssetsIfInfo");
        InstanceServiceImpl instanceService = (InstanceServiceImpl) this.cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<String> groupIds = Arrays.asList(SpringUtils.getPropertiesValue("base.network.groupId"), SpringUtils.getPropertiesValue("base.safeEquip.groupId"), SpringUtils.getPropertiesValue("base.mwServer.groupId"));

        List<InstanceInfo> instanceInfoList = new ArrayList<>();
        for (String groupId : groupIds) {
            if (!StringUtils.hasText(groupId)) {
                continue;
            }
            InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
            instanceSearchParam.setGroupOrModelId(groupId);
            List<InstanceInfo> instanceInfos = instanceService.selectList(instanceSearchParam);
            if (null != instanceInfos && !instanceInfos.isEmpty()) {
                instanceInfoList.addAll(instanceInfos);
            }
        }
        //网络设备，安全设备，服务器获取
        if (null != instanceInfoList && !instanceInfoList.isEmpty()) {
            businessProcessNetwork.refreshIfInfo(instanceInfoList);
            kafkaTemplate.send(RefreshInterfaceTopic, RefreshInterfaceMapCache);
        }

    }

    @Override
    public void refreshAssetsIfInfoByInstanceId(String instanceId) throws Exception {
        //查询snmp资产并更新接口信息
        log.info("start refreshAssetsIfInfoByInstanceId,instanceId:{}", instanceId);
        InstanceServiceImpl instanceService = (InstanceServiceImpl) this.cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<InstanceInfo> instanceInfoList = new ArrayList<>();
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setInstanceId(instanceId);
        List<InstanceInfo> instanceInfos = instanceService.selectList(instanceSearchParam);
        if (null != instanceInfos && !instanceInfos.isEmpty()) {


            // 先查询当前实例接口信息,获取已配置列表展示的接口
            List<AssetsInterfaceDTO> assetsInterfaceDTOS = businessProcessNetwork.listAssetsInterfaces(Arrays.asList(instanceId))
                    .stream().filter(item -> item.getShowFlag() != null && item.getShowFlag()).toList();
            Map<Integer, AssetsInterfaceDTO> ifIndexId2AssetsInterface = assetsInterfaceDTOS.stream().collect(
                    Collectors.toMap(AssetsInterfaceDTO::getIfIndex, item -> item, (o1, o2) -> o2));

            instanceInfoList.addAll(instanceInfos);
            businessProcessNetwork.refreshIfInfo(instanceInfoList);
            // 重新刷新网络接口信息之后，恢复用户手动保存数据
            businessProcessNetwork.recoverCustomConfig(instanceId, ifIndexId2AssetsInterface);
            kafkaTemplate.send(RefreshInterfaceTopic, RefreshInterfaceMapCache);
        }
    }

    @Override
    public List<AssetsInterfaceView> getAssetsInterface(List<String> instanceIds) throws Exception {
        BusinessProcessNetwork businessProcessNetwork = SpringUtils.getBean(BusinessProcessNetwork.class);
        if (null != instanceIds && !instanceIds.isEmpty()) {
            List<AssetsInterfaceDTO> assetsInterfaceDTOS = businessProcessNetwork.listAssetsInterfaces(instanceIds);
            if (null != assetsInterfaceDTOS) {
                List<AssetsInterfaceView> assetsInterfaceViews = new ArrayList<>();
                for (AssetsInterfaceDTO assetsInterfaceDTO : assetsInterfaceDTOS) {
                    AssetsInterfaceView assetsInterfaceView = new AssetsInterfaceView();
                    BeanUtil.copyProperties(assetsInterfaceDTO, assetsInterfaceView, true);
                    assetsInterfaceViews.add(assetsInterfaceView);
                }
                return assetsInterfaceViews;
            }
        }
        return null;
    }

    @Override
    public Map<String, Integer> getAssetInterfaceStatusCount(SearchParam param) throws Exception {
        String systemInterfaceConfig = SpringUtils.getPropertiesValue(systemInterfaceConfigKey);
        param.setSearchClass(AssetsInterfaceDTO.class);
        if (CriteriaOpsType.keyword.name().equals(param.getOperation()) && org.apache.commons.lang3.StringUtils.isEmpty(param.getKeywordValue())) {
            param.setOperation(null);
        }
        Criteria criteria = genCriteria(param);
        if (!SCMONITORSYSTEMKEY.equals(systemInterfaceConfig)) {
            // 列表显示接口:设置showFlag=true+默认显示up状态接口
            criteria.orOperator(CriteriaWrapper.where(AssetsInterfaceDTO::getShowFlag).is(true),
                    CriteriaWrapper.where(AssetsInterfaceDTO::getShowFlag).isNull().orOperator(CriteriaWrapper.where(AssetsInterfaceDTO::getState).is(IfStatus.up.name())));
        }
        param.setPage(null);
        GroupSearchOperation groupSearchOperation = new GroupSearchOperation();
        String groupName = CMDBTool.getFieldName(AssetsInterfaceDTO::getState);
        groupSearchOperation.addGroupField(CMDBTool.getFieldName(AssetsInterfaceDTO::getState), groupName);
        groupSearchOperation.addCalculateField(CMDBTool.getFieldName(AssetsInterfaceCountDTO::getCount), GroupCalculateMethodEnum.count, groupName);
        List<AssetsInterfaceCountDTO> result = CMDBTool.selectCountByAggregate(AssetsInterfaceCountDTO.class, assetsInterfaceMapper, criteria, groupSearchOperation);
        Map<String, Integer> status2CountMap = new LinkedHashMap<>();
        status2CountMap.put(IfStatus.up.name(), 0);
        status2CountMap.put(IfStatus.down.name(), 0);
        if (CollectionUtils.isNotEmpty(result)) {
            Map<String, Integer> queryMap = result.stream().collect(Collectors.toMap(AssetsInterfaceCountDTO::getId, AssetsInterfaceCountDTO::getCount));
            for (Map.Entry<String, Integer> item : queryMap.entrySet()) {
                if (status2CountMap.containsKey(item.getKey())) {
                    status2CountMap.put(item.getKey(), status2CountMap.get(item.getKey()) + item.getValue());
                } else {
                    status2CountMap.put(item.getKey(), item.getValue());
                }
            }
        }
        return status2CountMap;
    }

    @Override
    public Object getAssetAllInterfaceByPage(SearchParam param) throws Exception {
        param.setSearchClass(AssetsInterfaceDTO.class);
        if (StringUtils.isEmpty(param.getKeywordValue()) && CriteriaOpsType.keyword.name().equals(param.getOperation())) {
            param.setOperation(null);
        }
        String mwInstanceId = "";
        Map<String, SubCondition> condition = param.getCondition();
        Criteria criteria = new Criteria();
        if (condition != null && condition.containsKey(InstanceIdKey)) {
            SubCondition subCondition = condition.get(InstanceIdKey);
            mwInstanceId = strValueConvert(subCondition.getValue());
            criteria.andOperator(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(mwInstanceId));
        }
        //保留原始分页信息
        MWPage pageOld = param.getPage();
        MWPage page = new MWPage();
        page.setCurrent(pageOld.getCurrent());
        page.setSize(pageOld.getSize());
        //设置大数据分页，查询所有数据
        MWPage pages = pageOld;
        pages.setSize(100000);
        pages.setCurrent(1l);
        param.setPage(pages);
        List<AssetsInterfaceDTO> resultList = CMDBTool.selectPageList(assetsInterfaceMapper, criteria, param);
        //交换机特殊处理
        for (AssetsInterfaceDTO assetsInterfaceDTO : resultList) {
            if (assetsInterfaceDTO.getShowFlag() == null) {
                boolean ifModeFlag = IfMode.trunk.name().equals(assetsInterfaceDTO.getIfMode());
                boolean interfaceNameFlag = assetsInterfaceDTO.getName().contains(INTERFACE_NAME_VLAN_KEY);
                boolean statusFlag = IfStatus.up == assetsInterfaceDTO.getState();
                //类型时Trunk + up的
                //接口名称包含Vlan + up的
                if (statusFlag && (ifModeFlag || interfaceNameFlag)) {
                    assetsInterfaceDTO.setShowFlag(true);
                } else {
                    assetsInterfaceDTO.setShowFlag(false);
                }
            }
            assetsInterfaceDTO.setConvertName(getShortName(assetsInterfaceDTO.getName()));
        }
        //排序
        Collections.sort(resultList, new AlphanumericComparator(CMDBTool.getFieldName(AssetsInterfaceView::getName), param.getSortName(), param.getSortOrder()));
        if (condition != null) {
            condition.remove(InstanceIdKey);
            Set<String> keySet = condition.keySet();
            Map<String, Object> ms = new HashMap<>();
            for (String key : keySet) {
                SubCondition subCondition = condition.get(key);
                ms.put(key, subCondition.getValue());
            }
            //数据过滤
            resultList = filterListByMap(resultList, ms);
        }
        ViewConvertContext context = new ViewConvertContext();
        param.setPage(page);
        return viewManager.getListViewObject(resultList, AssetsInterfaceDTO.class, param, context);
    }

    @Override
    public Object getAssetShowInterfaceByPage(SearchParam param) throws Exception {
        String systemInterfaceConfig = SpringUtils.getPropertiesValue(systemInterfaceConfigKey);
        param.setSearchClass(AssetsInterfaceDTO.class);
        if (StringUtils.isEmpty(param.getKeywordValue()) && CriteriaOpsType.keyword.name().equals(param.getOperation())) {
            param.setOperation(null);
        }
        String mwInstanceId = "";
        Map<String, SubCondition> condition = param.getCondition();
        Criteria criteria = new Criteria();
        if (condition != null && condition.containsKey(InstanceIdKey)) {
            SubCondition subCondition = condition.get(InstanceIdKey);
            mwInstanceId = strValueConvert(subCondition.getValue());
            criteria.andOperator(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(mwInstanceId));
        }
        //保留原始分页信息
        MWPage pageOld = param.getPage();
        MWPage page = new MWPage();
        page.setCurrent(pageOld.getCurrent());
        page.setSize(pageOld.getSize());
        //设置大数据分页，查询所有数据
        MWPage pages = pageOld;
        pages.setSize(100000);
        pages.setCurrent(1l);
        param.setPage(pages);
        List<AssetsInterfaceDTO> resultList = CMDBTool.selectPageList(assetsInterfaceMapper, criteria, param);
        //获取交换机模型下的实例Id
        String switchModelId = SpringUtils.getPropertiesValue("base.network.switch.modelId");

        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setInstanceId(mwInstanceId);
        InstanceServiceImpl instanceService = (InstanceServiceImpl) this.cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceInfo instanceInfo = instanceService.selectById(mwInstanceId);
        String hostId = instanceInfo.getMonitorTypeId();
        Integer monitorServerId = instanceInfo.getMonitorServerId();

        String modelId = instanceInfo.getModelId();
        //交换机下的接口
        List<AssetsInterfaceDTO> disList = new ArrayList<>();
        List<String> allInterfaceNames = new ArrayList<>();
        boolean falseFlag = false;
        if (SCMONITORSYSTEMKEY.equals(systemInterfaceConfig)) {
            disList = resultList;
        } else {
            if (CollectionUtils.isNotEmpty(resultList)) {
                allInterfaceNames = resultList.stream().filter(s -> !Strings.isNullOrEmpty(s.getName())).map(s -> s.getName()).collect(Collectors.toList());
                disList = resultList.stream().filter(s -> s.getShowFlag() != null && s.getShowFlag()).collect(Collectors.toList());
                List<AssetsInterfaceDTO> falseDisList = resultList.stream().filter(s -> s.getShowFlag() != null && !s.getShowFlag()).collect(Collectors.toList());
                //如果接口数据全是showFlag为false的，过滤
                falseFlag = falseDisList.size() == resultList.size();
            }
        }
        if (!falseFlag && CollectionUtils.isEmpty(disList)) {
            //如果disList为空，表示showFlag未设置，则进行初始规则过滤
            List<String> names = new ArrayList<>();
            for (AssetsInterfaceDTO assetsInterfaceDTO : resultList) {
                boolean statusFlag = IfStatus.up == assetsInterfaceDTO.getState();
                if (statusFlag && assetsInterfaceDTO.getAlertFlag() == null) {
                    //告警状态 up的默认为true
                    assetsInterfaceDTO.setAlertFlag(true);
                }
                //交换机初始化显示
                if (switchModelId.equals(modelId)) {
                    assetsInterfaceDTO.setConvertName(getShortName(assetsInterfaceDTO.getName()));
                    boolean ifModeFlag = IfMode.trunk.name().equals(assetsInterfaceDTO.getIfMode());
                    boolean interfaceNameFlag = assetsInterfaceDTO.getName().contains(INTERFACE_NAME_VLAN_KEY);
                    assetsInterfaceDTO.setShowFlag(true);
                    assetsInterfaceDTO.setAlertFlag(true);
                    assetsInterfaceDTO.setEditorFlag(true);
                    assetsInterfaceDTO.setItemFlag(true);
                    //类型时Trunk + up的
                    //接口名称包含Vlan + up的
                    if (statusFlag && (ifModeFlag || interfaceNameFlag)) {
                        names.add(assetsInterfaceDTO.getName());
                        disList.add(assetsInterfaceDTO);
                    }
                } else {
                    if (statusFlag) {
                        names.add(assetsInterfaceDTO.getName());
                        disList.add(assetsInterfaceDTO);
                    }
                }
            }
            //修改接口数据
            batchUpdateInterfaceList(disList);
            ZabbixHandlerParam zabbixHandlerParam = new ZabbixHandlerParam();
            zabbixHandlerParam.setInterfaceNames(names);
            zabbixHandlerParam.setServerId(monitorServerId);
            zabbixHandlerParam.setHostId(hostId);
            //更新自动发现规则过滤信息(状态为显示的才生成自动发现规则)
            zabbixHandlerParam.setStatus(true);
            allInterfaceNames.removeAll(names);
            zabbixHandlerParam.setDisplayInterfaceList(allInterfaceNames);
            //开启自动发现规则
            mwZabbixHandlerService.updateDiscoveryRuleFilterInfo(zabbixHandlerParam);
            //开启告警触发器
            mwZabbixHandlerService.interfaceTriggerDeactivate(zabbixHandlerParam);
            mwZabbixHandlerService.updateMonitorItemStatus(zabbixHandlerParam);
        }
        List<AssetsInterfaceView> assetsInterfaceViews = new ArrayList<>();
        for (AssetsInterfaceDTO assetsInterfaceDTO : disList) {
            AssetsInterfaceView assetsInterfaceView = new AssetsInterfaceView();
            BeanUtil.copyProperties(assetsInterfaceDTO, assetsInterfaceView, true);
            assetsInterfaceViews.add(assetsInterfaceView);
        }
        if (CollectionUtils.isNotEmpty(assetsInterfaceViews)) {
            if (monitorServerId != null && StringUtils.hasText(hostId)) {
                // 查询监控项信息
                List<String> itemNames = Arrays.asList(InterfaceInfoEnum.MW_INTERFACE_OUT_TRAFFIC.getName(),
                        InterfaceInfoEnum.MW_INTERFACE_IN_TRAFFIC.getName(),
                        InterfaceInfoEnum.MW_INTERFACE_OUT_DROPPED.getName(),
                        InterfaceInfoEnum.MW_INTERFACE_IN_DROPPED.getName(),
                        InterfaceInfoEnum.MW_INTERFACE_SPEED.getName(),
                        InterfaceInfoEnum.INTERFACE_IN_UTILIZATION.getName(),
                        InterfaceInfoEnum.INTERFACE_OUT_UTILIZATION.getName(),
                        InterfaceInfoEnum.INTERFACE_MTU.getName(),
                        InterfaceInfoEnum.INTERFACE_INDEX.getName(), InterfaceInfoEnum.INTERFACE_DESCR.getName(), InterfaceInfoEnum.MW_INTERFACE_STATUS.getName());
                MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_HOST_IDS_SEARCH, monitorServerId, itemNames, Arrays.asList(hostId));
                List<ItemGetDTO> itemGetDTOList;
                if (mwZabbixAPIResult != null && mwZabbixAPIResult.isSuccess()) {
                    itemGetDTOList = JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult.getData()), ItemGetDTO.class);
                    dataConvert(itemGetDTOList, assetsInterfaceViews, monitorServerId);
                }
            }
            for (AssetsInterfaceView assetsInterfaceView : assetsInterfaceViews) {
                assetsInterfaceView.setConvertName(getShortName(assetsInterfaceView.getName()));
            }
        }
        //排序
        Collections.sort(assetsInterfaceViews, new AlphanumericComparator(CMDBTool.getFieldName(AssetsInterfaceView::getName), param.getSortName(), param.getSortOrder()));
        if (condition != null) {
            condition.remove(InstanceIdKey);
            Set<String> keySet = condition.keySet();
            Map<String, Object> ms = new HashMap<>();
            for (String key : keySet) {
                SubCondition subCondition = condition.get(key);
                ms.put(key, subCondition.getValue());
            }
            //数据过滤
            assetsInterfaceViews = filterListByMap(assetsInterfaceViews, ms);
        }
        ViewConvertContext context = new ViewConvertContext();
        param.setPage(page);
        return viewManager.getListViewObject(assetsInterfaceViews, AssetsInterfaceView.class, param, context);
    }


    public static String getShortName(String name) {
        return name.replaceAll("TwoGigabitEthernet", "Tw")
                .replaceAll("TenGigabitEthernet", "Te")
                .replaceAll("AppGigabitEthernet", "Ap")
                .replaceAll("FortyGigabitEthernet", "Fo")
                .replaceAll("GigabitEthernet", "Gi")
                .replaceAll("FastEthernet", "Fa")
                .replaceAll("Bluetooth", "Bl")
                .replaceAll("Ethernet", "Eth");
    }

    public void dataConvert(List<ItemGetDTO> itemGetDTOList, List<AssetsInterfaceView> assetsInterfaceViews, Integer monitorServerId) {
        Map<String, List<ItemGetDTO>> collect = itemGetDTOList.stream().collect(Collectors.groupingBy(ItemGetDTO::getOriginalType));
        Map<Integer, AssetsInterfaceView> ifIndex2InfoMap = assetsInterfaceViews.stream().collect(Collectors.toMap(AssetsInterfaceView::getIfIndex, item -> item, (o1, o2) -> o1));
        Map<String, AssetsInterfaceView> name2InfoMap = assetsInterfaceViews.stream().collect(Collectors.toMap(AssetsInterfaceView::getName, item -> item, (o1, o2) -> o1));

        List<String> valuemapIds = new ArrayList<>();
        for (ItemGetDTO item : itemGetDTOList) {
            String valuemapid = item.getValuemapid();
            valuemapIds.add(valuemapid);
        }
        List<String> valuemapIdList = valuemapIds.stream().distinct().collect(Collectors.toList());
        Map<String, Map> valueMapByIdMap = getValueMapByIdList(monitorServerId, valuemapIdList);

        for (Map.Entry<String, List<ItemGetDTO>> value : collect.entrySet()) {
            List<ItemGetDTO> dtos = value.getValue();
            Double inTrafficValue = null;
            Double outTrafficValue = null;
            String ifIndex = null;
            String interfaceName = value.getKey().replace("[", "").replace("]", "");
            for (ItemGetDTO dto : dtos) {
                String name = dto.getName();
                if (InterfaceInfoEnum.MW_INTERFACE_IN_TRAFFIC.getName().equals(name)) {
                    inTrafficValue = dto.getSortLastValue();
                }
                if (InterfaceInfoEnum.MW_INTERFACE_OUT_TRAFFIC.getName().equals(name)) {
                    outTrafficValue = dto.getSortLastValue();
                }
                if (InterfaceInfoEnum.INTERFACE_INDEX.getName().equals(name)) {
                    ifIndex = dto.getLastvalue();
                }
            }
            AssetsInterfaceView assetsInterfaceView = null;
            if (ifIndex != null) {
                assetsInterfaceView = ifIndex2InfoMap.get(Integer.valueOf(ifIndex));
            }
            if (assetsInterfaceView == null) {
                assetsInterfaceView = name2InfoMap.get(interfaceName);
            }
            if (assetsInterfaceView == null) {
                continue;
            }
            Double finalInTrafficValue = inTrafficValue;
            Double finalOutTrafficValue = outTrafficValue;

            for (ItemGetDTO itemGetDTO : dtos) {
                String name = itemGetDTO.getName();
                String lastvalue = itemGetDTO.getLastvalue();
                InterfaceInfoEnum itemName = InterfaceInfoEnum.valueOf(name.substring(name.indexOf("]") + 1));
                switch (itemName) {
                    case MW_INTERFACE_OUT_TRAFFIC:
                        assetsInterfaceView.setOutBps(lastvalue);
                        break;
                    case MW_INTERFACE_IN_TRAFFIC:
                        assetsInterfaceView.setInBps(lastvalue);
                        break;
                    case MW_INTERFACE_OUT_DROPPED:
                        assetsInterfaceView.setSendLoss(lastvalue);
                        break;
                    case MW_INTERFACE_IN_DROPPED:
                        assetsInterfaceView.setAcceptLoss(lastvalue);
                        break;
                    case MW_INTERFACE_SPEED:
                        assetsInterfaceView.setRate(lastvalue);
                        break;
                    case INTERFACE_IN_UTILIZATION:
                        String val = lastvalue.replaceAll("[a-zA-Z%]", "");
                        BigDecimal bValue = new BigDecimal(val);
                        if (val.indexOf(".") != -1) {
                            val = bValue.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
                        }
                        if (finalInTrafficValue.intValue() == 0) {
                            assetsInterfaceView.setInBpsRatio("0");
                        } else {
                            assetsInterfaceView.setInBpsRatio(val);
                        }
                        break;
                    case INTERFACE_OUT_UTILIZATION:
                        String outVal = lastvalue.replaceAll("[a-zA-Z%]", "");
                        BigDecimal outValue = new BigDecimal(outVal);
                        if (outVal.indexOf(".") != -1) {
                            outVal = outValue.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
                        }
                        if (finalOutTrafficValue.intValue() == 0) {
                            assetsInterfaceView.setOutBpsRatio("0");
                        } else {
                            assetsInterfaceView.setOutBpsRatio(outVal);
                        }
                        break;
                    case MW_INTERFACE_STATUS:
                        String valuemapid = itemGetDTO.getValuemapid();
                        if (valueMapByIdMap != null && valueMapByIdMap.size() > 0 &&
                                valueMapByIdMap.get(valuemapid) != null && valueMapByIdMap.get(valuemapid).get(lastvalue) != null) {
                            String newvalue = valueMapByIdMap.get(valuemapid).get(lastvalue).toString();
                            if (!Strings.isNullOrEmpty(newvalue)) {
                                assetsInterfaceView.setState(newvalue);
                            }
                        }
                        break;
                    case INTERFACE_MTU:
                        assetsInterfaceView.setMtu(lastvalue != null ? Integer.valueOf(lastvalue) : 0);
                        break;
                    case INTERFACE_MACADDR:
                        assetsInterfaceView.setMac(lastvalue);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    //根据item中valuemapid属性，转换成对应的value值
    public Map<String, Map> getValueMapByIdList(int monitorServerId, List<String> valuemapId) {
        try {
            MWZabbixAPIResult valueMapById = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_VALUE_MAP_BY_ID, monitorServerId, valuemapId);
            List<ValuemapDto> dataList = new ArrayList<>();
            if (null != valueMapById && valueMapById.getCode() == 0) {
                dataList = JSONArray.parseArray(JSON.toJSONString(valueMapById.getData()), ValuemapDto.class);
            }
            Map<String, Map> map = new HashMap();
            for (ValuemapDto dto : dataList) {
                Map map1 = new HashMap();
                for (ValueMappingDto val : dto.getMappings()) {
                    val.getValue();
                    val.getNewvalue();
                    map1.put(val.getValue(), val.getNewvalue());
                }
                map.put(dto.getValuemapid(), map1);
            }
            return map;
        } catch (Exception e) {
            log.error("getValueMapByIdList error!", e);
            return null;
        }
    }

    @Override
    public boolean editInterfaceFlag(MwAssetsInterfaceParam param) throws Exception {
        // 只更新手动设置了showFlag的接口
        Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(param.getInstanceId()).andOperator(
                CriteriaWrapper.where(AssetsInterfaceDTO::getId).in(param.getIds())
        ));
        Update update = new Update();
        if (SHOW_FLAG_KEY.equals(param.getType())) {
            update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getShowFlag), param.getShowFlag());
            update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getAlertFlag), param.getShowFlag());
            update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getItemFlag), param.getShowFlag());
        }
        if (ALERT_FLAG_KEY.equals(param.getType())) {
            update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getAlertFlag), param.getAlertFlag());
        }
        if (ITEM_FLAG_KEY.equals(param.getType())) {
            update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getItemFlag), param.getItemFlag());
        }
        update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getEditorFlag), true);
        assetsInterfaceMapper.updateMulti(query, update);

        //勾选或者开启监控时，把不匹配的设为false
        if (param.getShowFlag() != null && param.getShowFlag()) {
            query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(param.getInstanceId()).andOperator(
                    CriteriaWrapper.where(AssetsInterfaceDTO::getId).nin(param.getIds())
            ));
            update = new Update();
            if (SHOW_FLAG_KEY.equals(param.getType())) {
                update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getShowFlag), false);
                update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getAlertFlag), false);
                update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getItemFlag), false);
            }
            assetsInterfaceMapper.updateMulti(query, update);
        }
        return true;
    }

    @Override
    public void editInterfaceDesc(AssetsInterfaceDTO param) throws Exception {
        // 更新接口描述信息
        Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getId).is(param.getId()));
        Update update = new Update();
        update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getAlias), param.getAlias());
        //设置修改标识
        update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getEditorFlag), true);
        assetsInterfaceMapper.updateMulti(query, update);
    }

    @Override
    public void deleteInterfaceInfo(MwAssetsInterfaceParam param) throws Exception {
        Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getId).in(param.getIds()));
        Update update = new Update();
        update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getShowFlag), false);
        update.set(DatabaseUtils.getFieldName(AssetsInterfaceDTO::getAlertFlag), false);
        assetsInterfaceMapper.updateMulti(query, update);
    }


    private void doMonitor(MonitorValue monitorValue, MonitorParamContext context, Consumer<MonitorProcessor> action) throws Exception {
        //检查监控服务器类型
        Integer monitorServerId = monitorValue.getMonitorServerId();
        MwTPServerTable mwTPServerTable = mwTPServerService.getMwTPServerByServiceId(monitorServerId);
        if (null == mwTPServerTable) {
            throw new FindNoException("find-no-server-error");
        }

        //查询分组信息
        ModelGroupServiceImpl modelGroupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        ModelGroupInfo query = new ModelGroupInfo();
        query.setId(((InstanceInfo) monitorValue).getGroupId());
        ModelGroupInfo modelGroupInfo = modelGroupService.doSelectById(query);
        if (null == modelGroupInfo && null == modelGroupInfo.getMonitorGroupInfos()) {
            throw new FindNoException("find-no-group-error");
        }

        MonitorGroupInfo matchMonitorGroupInfo = null;
        for (MonitorGroupInfo monitorGroupInfo : modelGroupInfo.getMonitorGroupInfos()) {
            if (monitorServerId.equals(Integer.valueOf(monitorGroupInfo.getServerId()))) {
                matchMonitorGroupInfo = monitorGroupInfo;
                break;
            }
        }

        if (null == matchMonitorGroupInfo) {
            throw new FindNoException("find-no-group-error");
        }
        monitorValue.setHostGroupId(intValueConvert(matchMonitorGroupInfo.getGroupid()));
        ModelTemplateInfo modelTemplateInfo = new ModelTemplateInfo();
        //查询模版信息 自动识别(扫描模式)返回识别后的TemplateId，
        ModelTemplateServiceImpl modelTemplateService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        if (!Strings.isNullOrEmpty(monitorValue.getTemplateId())) {
            modelTemplateInfo = modelTemplateService.doSelectById(monitorValue.getTemplateId());
        }//手动添加时，只能传模板名称厂商规格型号等信息，需匹配对应模板
        if (Strings.isNullOrEmpty(monitorValue.getTemplateId()) && monitorValue instanceof InstanceInfo) {
            TemplateSearchParam searchParam = ((InstanceInfo) monitorValue).getTemplateSearchParam();
            List<ModelTemplateInfo> templateInfos = modelTemplateService.doSelectList(searchParam);
            if (CollectionUtils.isNotEmpty(templateInfos)) {
                modelTemplateInfo = templateInfos.get(0);
            }
        }
        if (null == modelTemplateInfo || null == modelTemplateInfo.getServerTemplates()) {
            throw new FindNoException("find-no-template-error");
        }
        ServerTemplateInfo matchServerTemplateInfo = null;
        for (ServerTemplateInfo serverTemplateInfo : modelTemplateInfo.getServerTemplates()) {
            if (monitorServerId.equals(Integer.valueOf(serverTemplateInfo.getServerId()))) {
                matchServerTemplateInfo = serverTemplateInfo;
                break;
            }
        }

        if (null == matchServerTemplateInfo) {
            throw new FindNoException("find-no-template-error");
        }
        monitorValue.setHostTemplateId(matchServerTemplateInfo.getServerTemplateId());

        //获取服务器对应的分组id和模版id
        //判断是否立即加入监控
        boolean executeNow = null == monitorValue.getCheckNowFlag() ? false : monitorValue.getCheckNowFlag();
        log.info("executeNow is {}", executeNow);
//        if(!executeNow){
//            return;
//        }

        if (null != mwTPServerTable && StringUtils.hasText(mwTPServerTable.getMonitoringServerType())) {
            //获取轮训引擎信息
            MwEngineManageTableDto mwEngineManage = mwEngineManageService.getEngineManageByEngineId(monitorValue.getPollingEngine());
            String proxyId = (null == mwEngineManage ? null : mwEngineManage.getProxyId());
            MonitoringServerType type = MonitoringServerType.valueOf(mwTPServerTable.getMonitoringServerType());
            switch (type) {
                case Zabbix:
                    context.setZabbixProxyId(proxyId);
                    context.setZabbixDubboService(zabbixDubboService);
                    break;
                default:
            }

            MonitorProcessor processor = MonitorProcessor.build(mwTPServerTable, Arrays.asList(monitorValue));
            action.accept(processor);
        }
    }

    /**
     * 批量纳管参数转换
     *
     * @param monitorValueList
     * @param context
     * @param action
     * @throws Exception
     */
    private void doBatchMonitor(List<? extends MonitorValue> monitorValueList, MonitorParamContext context, Consumer<MonitorProcessor> action) throws Exception {
        Set<Integer> monitorServerIds = new HashSet<>();
        Set<String> groupSet = new HashSet<>();
        Set<String> templateIdSet = new HashSet<>();
        List<SearchParam> searchParamList = new ArrayList<>();
        //立即执行的实例Id列表
        List<String> executeNowInstanceIds = new ArrayList<>();
        //初始化数据
        for (MonitorValue monitorValue : monitorValueList) {
            //检查监控服务器类型
            groupSet.add(((InstanceInfo) monitorValue).getGroupId());
            monitorServerIds.add(monitorValue.getMonitorServerId());
            //资产模板id信息
            if (!Strings.isNullOrEmpty(monitorValue.getTemplateId())) {
                templateIdSet.add(monitorValue.getTemplateId());
            }
            //资产模板查询信息
            if (Strings.isNullOrEmpty(monitorValue.getTemplateId()) && monitorValue instanceof InstanceInfo) {
                TemplateSearchParam searchParam = ((InstanceInfo) monitorValue).getTemplateSearchParam();
                searchParamList.add(searchParam);
            }
            //是否立即执行
            boolean executeNow = (null == monitorValue.getCheckNowFlag()) ? false : monitorValue.getCheckNowFlag();
            if (executeNow) {
                executeNowInstanceIds.add(monitorValue.getId());
            }
        }

        List<Integer> monitorServerIdList = new ArrayList<>(monitorServerIds);
        List<MwTPServerTable> mwTPServerTableList = mwTPServerService.getMwTPServerByServiceIds(monitorServerIdList);
        if (CollectionUtils.isEmpty(mwTPServerTableList)) {
            throw new FindNoException("find-no-server-error");
        }
        //查询分组信息
        List<String> groupList = new ArrayList<>(groupSet);
        ModelGroupServiceImpl modelGroupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        List<ModelGroupInfo> modelGroupList = modelGroupService.doSelectByIds(groupList);
        if (CollectionUtils.isEmpty(modelGroupList)) {
            throw new FindNoException("find-no-group-error");
        }
        //modelGroupList装为模型分组Id为key，MonitorGroupInfo的serverid和groupid转为map 做value
        Map<String, Map<Integer, Object>> resultMap = modelGroupList.stream()
                .collect(Collectors.toMap(ModelGroupInfo::getId, bean -> bean.getMonitorGroupInfos().stream()
                        .collect(Collectors.toMap(MonitorGroupInfo::getServerId, MonitorGroupInfo::getGroupid)), (o1, o2) -> o1));

        List<String> templateIds = new ArrayList<>(templateIdSet);
        List<ModelTemplateInfo> templateInfos = new ArrayList<>();
        ModelTemplateInfo modelTemplateInfo = new ModelTemplateInfo();
        //查询模版信息 自动识别(扫描模式)返回识别后的TemplateId，
        ModelTemplateServiceImpl modelTemplateService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);
        if (CollectionUtils.isNotEmpty(templateIdSet) && CollectionUtils.isNotEmpty(modelTemplateService.doSelectByIds(templateIds))) {
            templateInfos.addAll(modelTemplateService.doSelectByIds(templateIds));
        }//手动添加时，只能传模板名称厂商规格型号等信息，需匹配对应模板
        if (CollectionUtils.isNotEmpty(searchParamList)) {
            TemplateSearchParam searchParam = new TemplateSearchParam();
            searchParam.or().setSearchParamList(searchParamList);
            if (CollectionUtils.isNotEmpty(modelTemplateService.doSelectList(searchParam))) {
                templateInfos.addAll(modelTemplateService.doSelectList(searchParam));
            } else {
                throw new FindNoException("find-no-template-brand-error");
            }
        }
        if (CollectionUtils.isEmpty(templateInfos)) {
            throw new FindNoException("find-no-template-error");
        }

        //templateInfos组装，模板Id为key，将ServerTemplateInfo的serverid和ServerTemplateId转为的map做value
        Map<String, Map<Integer, Object>> templateMap = templateInfos.stream()
                .collect(Collectors.toMap(item -> item.getBrandId() + ":" + item.getSpecificationId() + ":" + item.getMonitorMode(), bean -> bean.getServerTemplates().stream()
                        .collect(Collectors.toMap(s -> intValueConvert(s.getServerId()), ServerTemplateInfo::getServerTemplateId)), (
                        value1, value2) -> {
                    return value2;
                }));
        Map mapParam = new HashMap();
        //获取轮询引擎信息
        Map proxyDataMap = getProxyDataByPollingEngine(monitorValueList);
        mapParam.put(PROXY_MAP_KEY, proxyDataMap);
        //按照监控服务器循环
        for (MwTPServerTable mwTPServerTable : mwTPServerTableList) {
            if (null != mwTPServerTable && StringUtils.hasText(mwTPServerTable.getMonitoringServerType())) {
                MonitoringServerType type = MonitoringServerType.valueOf(mwTPServerTable.getMonitoringServerType());
                int serverId = mwTPServerTable.getId();
                String monitoringServerName = mwTPServerTable.getMonitoringServerName();
                //主机群组信息转换
                Map<String, Object> groupInfoMapById = new HashMap<>();
                resultMap.forEach((k, v) -> {
                    String groupId = k;
                    Map<Integer, Object> monitorGroupMap = v;
                    if (monitorGroupMap != null && monitorGroupMap.containsKey(serverId)) {
                        Object monitorGroupId = monitorGroupMap.get(serverId);
                        groupInfoMapById.put(groupId, monitorGroupId);
                    }
                });
                mapParam.put(GROUP_MAP_KEY, groupInfoMapById);
                //模板信息转换
                Map<String, Object> templateInfoMapById = new HashMap<>();
                templateMap.forEach((k, v) -> {
                    String templatekey = k;
                    Map<Integer, Object> monitorTemplateMap = v;
                    if (monitorTemplateMap != null && monitorTemplateMap.containsKey(serverId)) {
                        Object monitorTempId = monitorTemplateMap.get(serverId);
                        templateInfoMapById.put(templatekey, monitorTempId);
                    }
                });
                if (templateInfoMapById != null && templateInfoMapById.size() == 0) {
                    throw new FindNotTemplateException(monitoringServerName);
                }
                mapParam.put(TEMPLATE_MAP_KEY, templateInfoMapById);
                context.setMapParam(mapParam);
                switch (type) {
                    case Zabbix:
                        context.setZabbixDubboService(zabbixDubboService);
                        break;
                    default:
                }
                MonitorProcessor processor = MonitorProcessor.build(mwTPServerTable, monitorValueList);
                action.accept(processor);
            }
        }


    }


    private ModelTemplateInfo matchAssetsInfo(RuleType rt, String sysObjectid, String sysDesc, String hostname
            , Map<String, ModelTemplateInfo> assetsOidMap, List<ModelTemplateInfo> modelTemplateList) {

        List<ModelTemplateInfo> filterList = new ArrayList<>();
        ModelTemplateInfo modelTemplateInfo = null;

        if (ICMP.getName().equals(rt.getName())) {
            List<ModelTemplateInfo> icmpTempList = modelTemplateList.stream().filter(s -> s.getTemplateName() != null && s.getTemplateName().contains(ICMP_Temp_Name)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(icmpTempList)) {
                return icmpTempList.get(0);
            }
        }

        log.info("try sysObjectid:[" + sysObjectid + "]");
        if (null != sysObjectid) {
            for (Map.Entry<String, ModelTemplateInfo> entry : assetsOidMap.entrySet()) {
                if (sysObjectid.equals(entry.getKey()) && null != entry.getValue()) {
                    if (sysDesc == null || !StringUtils.hasText(sysDesc)) {//当系统信息为空时，只匹配oid 返回匹配到的第一个相同的oid
                        return entry.getValue();
                    }
                    log.info("try entry.getValue:[" + entry.getValue() + "]");
                    filterList.add(entry.getValue());
                }
            }
        }
        if (null != sysObjectid) {
            modelTemplateList = filterList;
            log.info("modelTemplateList::!" + modelTemplateList);
        }
        if (debug) {
            log.info("try sysDesc:[" + sysDesc + "]");
        }
        boolean isFlag1 = false;
        for (ModelTemplateInfo item : modelTemplateList) {
            if (item.getMonitorMode() != null && item.getMonitorMode() != rt.getMonitorMode()) {
                if (debug) {
                    log.info("try item.getDescription():[" + item.getMonitorMode() + "]");
                }
                continue;
            }
            if (null != sysDesc) {
                if (debug) {
                    log.info("try item.getDescription():[" + item.getDescription() + "]");
                }
                boolean isFind = false;
                String description = "";
                if (!Strings.isNullOrEmpty(item.getDescription())) {
                    //使用正则进行数据匹配
                    description = item.getDescription().replace("\r\n", "").replace("\u200B", "");
                }
                sysDesc = sysDesc.replace("\r\n", "").replace("\u200B", "");//正则匹配去除换行符
                log.info("desc match server desc111:[{}],template desc:[{}]", sysDesc, description);
                if (StringUtils.hasText(description)) {
                    if (sysDesc.contains(description)) {
                        modelTemplateInfo = item;
                        log.info("desc match server desc:[{}],template desc:[{}]", sysDesc, item.getDescription());
                        return modelTemplateInfo;
                    }
                }
                //模板只匹配到OID，没有特征信息的
                if (Strings.isNullOrEmpty(description)) {
                    isFlag1 = true;//设置标识开关，匹配的模板是否都没有特征信息
                    log.info("description is empty:", isFlag1);
                }
                if (isFind) {
                    break;
                }
            }
        }
        if (isFlag1 && CollectionUtils.isNotEmpty(modelTemplateList)) {
            log.info("description::modelTemplateList:", modelTemplateList);
            return modelTemplateList.get(0);
        }
        return modelTemplateInfo;
    }

    /**
     * 批量处理 立即执行操作
     */
    public Boolean batchOpenNowItems(int monitorServerId, List<String> hostIds) {
        List<String> itemIds = new ArrayList<>();
        //所有自动发现规则的监控项id
        MWZabbixAPIResult resultDRules = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_DRULE_BY_HOST_ID, monitorServerId, hostIds);

        if (resultDRules != null && !resultDRules.isFail()) {
            List<DiscoveryRuleParam> discoveryRuleParams = JSONArray.parseArray(JSONArray.toJSONString(resultDRules.getData()), DiscoveryRuleParam.class);
            itemIds.addAll(discoveryRuleParams.stream().map(s -> s.getItemid()).collect(Collectors.toList()));
        }

        //所有的监控项id
        MWZabbixAPIResult resultItems = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_HOST_ID_LIST, monitorServerId, hostIds);
        if (resultItems != null && !resultItems.isFail()) {
            List<DiscoveryRuleParam> resultItemsParams = JSONArray.parseArray(JSONArray.toJSONString(resultItems.getData()), DiscoveryRuleParam.class);
            itemIds.addAll(resultItemsParams.stream().map(s -> s.getItemid()).collect(Collectors.toList()));
        }
        boolean isFlag = false;
        if (CollectionUtils.isNotEmpty(itemIds)) {
            //如果itemIds数量太多,需要分组
            List<List<String>> itemIdsGroups = Lists.partition(itemIds, batchFetchNum);
            for (List<String> itemIdSubList : itemIdsGroups) {
                //将所有的监控项进行是否立即执行 "6"是立即执行；"1"是诊断信息
                MWZabbixAPIResult result = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.TASK_ITEMS, monitorServerId, "6", itemIdSubList);
                if (result != null && !result.isFail()) {
                    if (result.getData() != null && result.getData() != null) {
                        MwItemCheckNowParam itemCheckNowParam = JSONObject.parseObject(JSON.toJSONString(result.getData()), MwItemCheckNowParam.class);
                        if (itemCheckNowParam.getTaskids() != null && itemCheckNowParam.getTaskids().size() > 0) {
                            return true;
                        }
                    }
                } else {
                    isFlag = false;
                }
            }
        }
        return isFlag;
    }


    private void setMatchTemplateInfo(ModelTemplateInfo modelTemplateInfo, ScanResultSuccess scanResultSuccess) {

        if (null != modelTemplateInfo) {
            scanResultSuccess.setBrand(modelTemplateInfo.getBrand());
            scanResultSuccess.setSpecification(modelTemplateInfo.getSpecification());
            scanResultSuccess.setBrandId(modelTemplateInfo.getBrandId());
            scanResultSuccess.setSpecificationId(modelTemplateInfo.getSpecificationId());
            scanResultSuccess.setGroupId(modelTemplateInfo.getModelGroupId());
            scanResultSuccess.setModelId(modelTemplateInfo.getModelId());
            scanResultSuccess.setTemplateId(modelTemplateInfo.getId());
            scanResultSuccess.setMw_templateName(modelTemplateInfo.getTemplateName());
            scanResultSuccess.setMw_monitorMode(scanResultSuccess.getRuleType().getMonitorMode());
            if (modelTemplateInfo.getTemplateName() != null && modelTemplateInfo.getTemplateName().contains(ICMP_Temp_Name)) {
                scanResultSuccess.setHostName("ICMP_" + scanResultSuccess.getIpAddress());
                scanResultSuccess.setInstanceName("ICMP_" + scanResultSuccess.getIpAddress());
                scanResultSuccess.setRuleType(RuleType.ICMP);
                scanResultSuccess.setPort(RuleType.ICMP.getPort());
            }
        } else {
            log.info("{} no match template!!" ,scanResultSuccess.getIpAddress());
        }

        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("CreateDate:{}", sdf.format(currentDate));
        scanResultSuccess.setCreateDate(currentDate);
        scanResultSuccess.setModificationDate(currentDate);
    }

    private static class ScanTask implements Callable<ScanResult> {
        private Authentication authentication;

        private AssetScanService assetScanService;
        private ScanParam scanParam;

        private CmdbServiceManage cmdbServiceManage;

        private AssetsScanParam assetsScanParam;

        private AssetsManageServiceImpl assetsManageService;

        private List<ModelTemplateInfo> modelTemplateInfos;

        private Address dubboRpcAddress;

        public ScanTask(Authentication authentication, AssetScanService assetScanService, ScanParam scanParam
                , CmdbServiceManage cmdbServiceManage, AssetsScanParam assetsScanParam
                , AssetsManageServiceImpl assetsManageService, List<ModelTemplateInfo> modelTemplateInfos, Address dubboRpcAddress) {
            this.authentication = authentication;
            this.assetScanService = assetScanService;
            this.scanParam = scanParam;
            this.cmdbServiceManage = cmdbServiceManage;
            this.assetsScanParam = assetsScanParam;
            this.assetsManageService = assetsManageService;
            this.modelTemplateInfos = modelTemplateInfos;
            this.dubboRpcAddress = dubboRpcAddress;
        }

        @Override
        public ScanResult call() throws Exception {
            try {
                SecurityContextHolder.getContext().setAuthentication(authentication);
                log.info("scanParam:{}", scanParam.toString());
                ScanResult scanResult = DubboUtils.invokeByAddress(new Function<ScanParam, ScanResult>() {
                    @Override
                    public ScanResult apply(ScanParam param) {
                        ScanResult ret = null;
                        try {
                            ret = assetScanService.scan(param);
                        } catch (Exception e) {
                            log.error("scan", e);
                        }
                        return ret;
                    }
                }, scanParam, dubboRpcAddress, (EchoService) assetScanService);
                log.info("scanResult:{}", scanResult.toString());
                //可能存在相同oid 不同特征信息，被覆盖的情况
                IdentityHashMap<String, ModelTemplateInfo> assetsOidMap = new IdentityHashMap<String, ModelTemplateInfo>();
                modelTemplateInfos.forEach(value -> {
                    if (null != value.getSystemObjid()) {
                        assetsOidMap.put(value.getSystemObjid().trim(), value);
                    }
                });

                //匹配信息
                List<ScanResultSuccess> scanResultSuccesses = scanResult.getScanResultSuccesses();
                if (null != scanResultSuccesses) {
                    for (ScanResultSuccess scanResultSuccess : scanResultSuccesses) {
                        ModelTemplateInfo matchTemplate = assetsManageService.matchAssetsInfo(scanResultSuccess.getRuleType()
                                , scanResultSuccess.getSysObjectid(), scanResultSuccess.getDescription()
                                , scanResultSuccess.getHostName(), assetsOidMap, modelTemplateInfos);

                        assetsManageService.setMatchTemplateInfo(matchTemplate, scanResultSuccess);
                    }

                    //设置扫描匹配成功结果信息
                    //进一步扫描并设置指纹信息指纹信息
                    scanResultSuccesses = DubboUtils.invokeByAddress(new Function<List<ScanResultSuccess>, List<ScanResultSuccess>>() {
                        @Override
                        public List<ScanResultSuccess> apply(List<ScanResultSuccess> successes) {
                            List<ScanResultSuccess> ret = null;
                            try {
                                List<String> ips = null;
                                if (null != successes) {
                                    ips = successes.stream().map(ScanResultSuccess::getIpAddress).collect(Collectors.toList());
                                    log.info("searchAndSetDeviceCode {}", ips);
                                }

                                ret = assetScanService.searchAndSetDeviceCode(successes);
                                log.info("finish searchAndSetDeviceCode {}", ips);
                            } catch (Exception e) {
                                log.error("searchAndSetDeviceCode", e);
                            }
                            return ret;
                        }
                    }, scanResultSuccesses, dubboRpcAddress, (EchoService) assetScanService);
                    scanResultSuccesses = assetScanService.searchAndSetDeviceCode(scanResultSuccesses);
                }
                scanResult.setScanResultSuccesses(scanResultSuccesses);
                return scanResult;
            } catch (InterruptedException interruptedException) {
                log.info("ScanTask is interrupted");
                return null;
            } catch (Exception e) {
                throw e;
            } finally {
                SecurityContextHolder.clearContext();
            }
        }
    }

    private void resetAssetInfo() {

    }

    private ScanResult getICMPAssetsScanResult(AssetsScanParam assetsScanParam) throws Exception {
        //信息匹配前准备,获取模版信息
        ModelTemplateServiceImpl modelTemplateService = (ModelTemplateServiceImpl) cmdbServiceManage.getModelService(ModelTemplateServiceImpl.ID);

        Query query = new Query(CriteriaWrapper.where(ModelTemplateInfo::getTemplateName).regex(ICMP_Temp_Name));
        List<ModelTemplateInfo> modelTemplateInfos = modelTemplateService.getListByQuery(query);
        ScanResult scanResult = new ScanResult();

        List<ScanResultSuccess> scanResultSuccesses = new ArrayList<>();
        ScanResultSuccess scanResultSuccess = new ScanResultSuccess();
        if (assetsScanParam != null && !Strings.isNullOrEmpty(assetsScanParam.getMw_inBandIp())) {
            scanResultSuccess.setHostName("ICMP_" + assetsScanParam.getMw_inBandIp());
            scanResultSuccess.setInstanceName("ICMP_" + assetsScanParam.getMw_inBandIp());
            scanResultSuccess.setIpAddress(assetsScanParam.getMw_inBandIp());
            if (CollectionUtils.isNotEmpty(modelTemplateInfos)) {
                ModelTemplateInfo modelTemplateInfo = modelTemplateInfos.get(0);
                scanResultSuccess.setRuleType(RuleType.ICMP);
                scanResultSuccess.setPort(RuleType.ICMP.getPort());
                scanResultSuccess.setSpecificationId(modelTemplateInfo.getSpecificationId());
                scanResultSuccess.setBrandId(modelTemplateInfo.getBrandId());
                scanResultSuccess.setModelId(modelTemplateInfo.getModelId());
                scanResultSuccess.setGroupId(modelTemplateInfo.getModelGroupId());
                scanResultSuccess.setTemplateId(modelTemplateInfo.getId());
                scanResultSuccess.setMw_templateName(modelTemplateInfo.getTemplateName());
                if (assetsScanParam.getMw_monitorServerId() != null) {
                    scanResultSuccess.setMonitorServerId(assetsScanParam.getMw_monitorServerId());
                }
                if (StringUtils.hasText(assetsScanParam.getMw_pollingEngine())) {
                    scanResultSuccess.setPollingEngine(assetsScanParam.getMw_pollingEngine());
                }
                scanResultSuccesses.add(scanResultSuccess);
            }
        }
        scanResult.setScanResultSuccesses(scanResultSuccesses);
        return scanResult;
    }

    public Map<String, String> getProxyDataByPollingEngine(List<? extends MonitorValue> monitorValueList) {
        Set<String> pollingEngineSet = new HashSet<>();
        Set<String> pollingEngineGroupSet = new HashSet<>();
        //初始化数据
        for (MonitorValue monitorValue : monitorValueList) {
            String pollingEngine = monitorValue.getPollingEngine();
            //引擎分组
            if (monitorValue.getProxyType() != null && monitorValue.getProxyType().intValue() == 2) {
                //分组id
                if (!Strings.isNullOrEmpty(pollingEngine)) {
                    pollingEngineGroupSet.add(pollingEngine);
                }
            } else {
                //轮询引擎
                if (!Strings.isNullOrEmpty(pollingEngine)) {
                    pollingEngineSet.add(pollingEngine);
                }
            }
        }
        Map<String, String> proxyIdById = new HashMap<>();
        List<String> pollingEngineList = new ArrayList<>(pollingEngineSet);
        if (CollectionUtils.isNotEmpty(pollingEngineList)) {
            List<MwEngineManageTableDto> engineManageByEngineInfoList = mwEngineManageService.getEngineManageByEngineIds(pollingEngineList);
            proxyIdById = engineManageByEngineInfoList.stream().filter(s -> s.getProxyId() != null).collect(Collectors.toMap(s -> s.getId(), s -> s.getProxyId(), (o1, o2) -> o1));
        }
        //获取轮训引擎分组信息
        List<String> pollingEngineGroupList = new ArrayList<>(pollingEngineGroupSet);
        if (CollectionUtils.isNotEmpty(pollingEngineGroupList)) {
            List<MwEngineProxyGroupInfo> engineProxyGroupInfoList = mwEngineManageService.getEngineProxyGroupInfoByIds(pollingEngineGroupList);
            proxyIdById = engineProxyGroupInfoList.stream().filter(s -> s.getProxyGroupId() != null).collect(Collectors.toMap(s -> strValueConvert(s.getId()), s -> s.getProxyGroupId(), (o1, o2) -> o1));
        }
        return proxyIdById;
    }

    public void initInterfaceSettingFlag() throws Exception {
        batchEditorInterfaceMonitor(null,null);
    }

    @Override
    public List<InstanceInfoExtend> doSelectInstanceList(Map param) throws Exception {
        InstanceServiceImpl modelService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        //根据模型视图判断是否是机房设备
        if (param != null && param.containsKey(defaultView.name())) {
            instanceSearchParam.setModelViewType(strValueConvert(param.get(defaultView.name())));
        }
        instanceSearchParam.setData(param);
        instanceSearchParam.convert();
        List<InstanceInfoExtend> instanceInfoList = modelService.aggregateList(instanceSearchParam);
        return instanceInfoList;
    }

    public void batchEditorInterfaceMonitor(List<String> ids,Boolean isTrunkFlag) throws Exception {
        String switchModelId = SpringUtils.getPropertiesValue("base.network.switch.modelId");
        InstanceServiceImpl instanceService = (InstanceServiceImpl) this.cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        //获取交换机模型下的实例Id
        List<String> instanceIds = new ArrayList<>();
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        if(CollectionUtils.isNotEmpty(ids)){
            instanceSearchParam.setInstanceIds(ids);
        }else{
            instanceSearchParam.setModelId(switchModelId);
        }
        List<InstanceInfo> instanceInfos = instanceService.selectList(instanceSearchParam);
        if (null != instanceInfos && !instanceInfos.isEmpty()) {
            instanceIds = instanceInfos.stream().map(s -> s.getId()).collect(Collectors.toList());
            log.info("batchEditorInterfaceMonitor::instanceIds数量:"+instanceIds.size()+";isTrunkFlag:"+isTrunkFlag);
        }
        BusinessProcessNetwork businessProcessNetwork = SpringUtils.getBean(BusinessProcessNetwork.class);
        if (null != instanceIds && !instanceIds.isEmpty()) {
            List<AssetsInterfaceDTO> assetsInterfaceDTOS = businessProcessNetwork.listAssetsInterfaces(instanceIds);
            Map<String, List<AssetsInterfaceDTO>> collect = assetsInterfaceDTOS.stream().filter(s -> s.getInstanceId() != null).collect(Collectors.groupingBy(s -> s.getInstanceId()));
            for (InstanceInfo instanceInfo : instanceInfos) {
                String hostId = instanceInfo.getMonitorTypeId();
                Integer serverId = instanceInfo.getMonitorServerId();
                String instanceId = instanceInfo.getId();
                List<String> names = new ArrayList<>();
                //是否trunk监控
                boolean trunkMonitorFlagKey = booleanValueConvert(instanceInfo.getTrunkMonitorFlagKey());
                if(isTrunkFlag!=null){
                    trunkMonitorFlagKey = isTrunkFlag;
                }
                if(ids ==null && isTrunkFlag == null){
                    //运维管理按钮操作，所有交换机全部按trunk处理
                    trunkMonitorFlagKey = true;
                }
                List<String> interfaceAllNames = new ArrayList<>();
                if (collect != null && collect.containsKey(instanceId)) {
                    List<AssetsInterfaceDTO> disAssetsInterfaceDTOS = collect.get(instanceId);
                    if (CollectionUtils.isNotEmpty(disAssetsInterfaceDTOS)) {
                        interfaceAllNames = disAssetsInterfaceDTOS.stream().map(s -> s.getName()).collect(Collectors.toList());
                        for (AssetsInterfaceDTO assetsInterfaceDTO : disAssetsInterfaceDTOS) {
                            //如果交换机接口,且trunk监控的
                            if (switchModelId.equals(instanceInfo.getModelId()) && trunkMonitorFlagKey) {
                                assetsInterfaceDTO.setConvertName(getShortName(assetsInterfaceDTO.getName()));
                                boolean ifModeFlag = IfMode.trunk.name().equals(assetsInterfaceDTO.getIfMode());
                                boolean interfaceNameFlag = assetsInterfaceDTO.getName().contains(INTERFACE_NAME_VLAN_KEY);
                                boolean statusFlag = IfStatus.up == assetsInterfaceDTO.getState();
                                //类型时Trunk + up的
                                //接口名称包含Vlan + up的
                                if (statusFlag && (ifModeFlag || interfaceNameFlag)) {
                                    assetsInterfaceDTO.setShowFlag(true);
                                    assetsInterfaceDTO.setAlertFlag(true);
                                    assetsInterfaceDTO.setEditorFlag(true);
                                    assetsInterfaceDTO.setItemFlag(true);
                                    names.add(assetsInterfaceDTO.getName());
                                }else{
                                    assetsInterfaceDTO.setShowFlag(false);
                                    assetsInterfaceDTO.setAlertFlag(false);
                                    assetsInterfaceDTO.setItemFlag(false);
                                }
                            } else {
                                if (IfStatus.up == assetsInterfaceDTO.getState()) {
                                    assetsInterfaceDTO.setShowFlag(true);
                                    assetsInterfaceDTO.setAlertFlag(true);
                                    assetsInterfaceDTO.setItemFlag(true);
                                    assetsInterfaceDTO.setEditorFlag(true);
                                    names.add(assetsInterfaceDTO.getName());
                                }else{
                                    assetsInterfaceDTO.setShowFlag(false);
                                    assetsInterfaceDTO.setAlertFlag(false);
                                    assetsInterfaceDTO.setItemFlag(false);
                                }
                            }
                        }
                    }

                }

                ZabbixHandlerParam zabbixHandlerParam = new ZabbixHandlerParam();
                zabbixHandlerParam.setInterfaceNames(names);
                zabbixHandlerParam.setServerId(serverId);
                zabbixHandlerParam.setHostId(hostId);
                if (!org.springframework.util.CollectionUtils.isEmpty(interfaceAllNames)) {
                    interfaceAllNames.removeAll(names);
                    zabbixHandlerParam.setDisplayInterfaceList(interfaceAllNames);
                }
                log.info("syncZabbixInterfaceMonitorInfo::" + strValueConvert(zabbixHandlerParam));
                //更新自动发现规则过滤信息(状态为显示的才生成自动发现规则)
                zabbixHandlerParam.setStatus(true);
                //开启自动发现规则
                mwZabbixHandlerService.updateDiscoveryRuleFilterInfo(zabbixHandlerParam);
                //开启告警触发器
                mwZabbixHandlerService.interfaceTriggerDeactivate(zabbixHandlerParam);
                mwZabbixHandlerService.updateMonitorItemStatus(zabbixHandlerParam);
            }
            //修改接口数据
            batchUpdateInterfaceList(assetsInterfaceDTOS);
        }

    }





    public void batchUpdateInterfaceList(List<AssetsInterfaceDTO> listInfo) throws Exception {
        List<Pair<Query, Update>> updateList = new ArrayList<>();
        for (AssetsInterfaceDTO entry : listInfo) {
            Query query = new Query(CriteriaWrapper.where(AssetsInterfaceDTO::getInstanceId).is(entry.getInstanceId()).andOperator(
                    CriteriaWrapper.where(AssetsInterfaceDTO::getIfIndex).is(entry.getIfIndex())
            ));
            Update update = CMDBTool.genMongoUpdate(entry, null, null);
            // 更新数据
            Pair<Query, Update> updatePair = Pair.of(query, update);
            updateList.add(updatePair);
        }
        if (!org.springframework.util.CollectionUtils.isEmpty(updateList)) {
            //UNORDERED是异步执行，有错误跳过继续执行；ORDERED时有序执行，遇到错误终止
            BulkOperations operations = assetsInterfaceMapper.bulkOps(BulkOperations.BulkMode.UNORDERED, AssetsInterfaceDTO.class);
            operations.updateMulti(updateList);
            operations.execute();
        }
    }

}
